package com.jplus.core.core.proxys;

import java.lang.reflect.Method;
import java.util.List;

import com.jplus.core.core.proxys.ProxyMethod.ProxyType;

/**
 * 代理链[无线程安全问题，代理对象每次执行方法前都会初始化当前类]，见CGlib,Ssist,jdk 代理过程
 */
public class ProxyChain {

	// 代理链
	private final List<Proxy> proxyList;
	// 必有
	private final Object proxyObject;// 代理对象
	private final ProxyMethod proxyMethod;// 代理方法
	private final Method targetMethod;// 原始方法
	private final Object[] methodParams;// 方法入参

	// 非必须
	private final Class<?>[] targetInterface;// 原始类 继承接口 [用于jdk 接口代理]
	private final Class<?> targetClass;// 原始类 [jdk没有]

	// ==================================================
	private int proxyIndex = 0;//

	/**
	 * 代理链
	 * 
	 * @param targetClass
	 *            被代理对象原始类
	 * @param targetInterface
	 *            被代理对象类接口
	 * @param proxyObject
	 *            生成的代理对象
	 * @param targetMethod
	 *            原始方法
	 * @param methodParams
	 *            方法入参
	 * @param proxyMethod
	 *            代理方法
	 * @param proxyList
	 *            代理链
	 * @param targetObject
	 *            原始类对象，如果有的话
	 */
	public ProxyChain(Class<?> targetClass, Class<?>[] targetInterface, Object proxyObject, Method targetMethod, Object[] methodParams, ProxyMethod proxyMethod, List<Proxy> proxyList) {
		this.targetClass = targetClass;
		this.targetInterface = targetInterface;
		this.proxyObject = proxyObject;
		this.targetMethod = targetMethod;
		this.methodParams = methodParams;
		this.proxyMethod = proxyMethod;
		this.proxyList = proxyList;
	}

	public Object doProxyChain() throws Throwable {
		if (proxyIndex < proxyList.size()) {
			Proxy proxy = proxyList.get(proxyIndex++);
			return proxy.doProxy(this);// 递归责任链
		} else {
			if (proxyMethod != null)
				return proxyMethod.invoke(proxyObject, methodParams);// 使用代理方法执行
		}
		return null;
	}

	public Object[] getMethodParams() {
		return methodParams;
	}

	public Class<?> getTargetClass() {
		return targetClass;
	}

	public Method getTargetMethod() {
		return targetMethod;
	}

	public Class<?>[] getTargetInterface() {
		return targetInterface;
	}

	public Object getProxyObject() {
		return proxyObject;
	}
	// 获取当前代理
	public Proxy getProxy() {
		return proxyList.get(proxyIndex - 1);
	}

	public int getProxyIndex() {
		return proxyIndex;
	}

	// 获取代理类型
	public ProxyType getProxyType() {
		return proxyMethod.getType();
	}
}
